package com.xxl.job.admin.api.interceptor;

import cn.hutool.json.JSONUtil;
import com.xxl.job.admin.api.config.CommonConstant;
import com.xxl.job.admin.api.model.XxlJobApiApp;
import com.xxl.job.admin.api.service.XxlJobApiAppService;
import com.xxl.job.core.biz.model.ReturnT;
import io.micrometer.core.instrument.util.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

import java.io.IOException;
import java.util.Objects;

/**
 * api验证拦截器
 */
@Component
public class ApiInterceptor implements AsyncHandlerInterceptor {
    @Autowired
    private CsrfCheck csrfCheck;
    @Autowired
    private XxlJobApiAppService xxlJobApiAppService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String timestamp = request.getHeader(CommonConstant.CSRF_TIMESTAMP);
        String sign = request.getHeader(CommonConstant.CSRF_SIGNATURE);
        String appId = request.getHeader(CommonConstant.CSRF_APPID);
        if(StringUtils.isBlank(timestamp) || StringUtils.isBlank(sign) || StringUtils.isBlank(appId)){
            setCallData(response);
            return false;
        }
        XxlJobApiApp byAppId = xxlJobApiAppService.findByAppId(appId);
        if(Objects.isNull(byAppId) || Objects.equals(byAppId.getEnable(), 0)){
            setCallData(response);
            return false;
        }
        boolean check = csrfCheck.checkSign(byAppId.getAppKey(), timestamp, sign);
        if(!check){
            setCallData(response);
        }
        return check;
    }

    private void setCallData(HttpServletResponse response){
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        response.setHeader("Access-Control-Allow-Origin","*");
        try {
            ReturnT<Object> res = new ReturnT<>(500, "签名校验失败！");
            response.getWriter().append(JSONUtil.toJsonStr(res));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
